#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include <android/log.h>

#include <sqlite3.h>

#include "mysqlite.h"

#define DEBUG_TAG "NDK_AndroidNDK1SampleActivity"

void Java_uk_co_droidinactu_CalibreImportIntf_importFile(JNIEnv * env, jobject this, jstring metadataFilename, jstring dbFilename) {
    jboolean isCopy;
    const char * szLogThis = (*env)->GetStringUTFChars(env, metadataFilename, &isCopy);

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);

    (*env)->ReleaseStringUTFChars(env, metadataFilename, szLogThis);

    //Open Database for writing
    sqlite3 *db;
   int rc = sqlite3_open(dbFilename, &db);

    //open calibre metadata file

    //loop over file

    	//read in record

    	//write record to db

    //loop

    //close metadata file

    //close db
    sqlite3_close(db);

    //end
}

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
    int i;
    for(i=0; i<argc; i++) {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

sqlite3* openDatabase(const char* dbFilename) {
    sqlite3* db;
    int rc;
    rc = sqlite3_open(dbFilename, &db);
    if( rc ) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return (0);
    }
    return db;
}

int sqlite3Test2(const char* dbFilename) {
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;

    //if( argc!=3 ) {
    //    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    //    return(1);
    //}
    rc = sqlite3_open(dbFilename, &db);
    //if( rc ) {
    //    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    //    sqlite3_close(db);
    //    return(1);
    //}
    //rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
    //if( rc!=SQLITE_OK ) {
    //    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    //    sqlite3_free(zErrMsg);
    //}
    sqlite3_close(db);
    return 0;
}

int sqlite3TestBind() {
    sqlite3 * db;
    char * sql;
    sqlite3_stmt * stmt;
    int nrecs;
    char * errmsg;
    int i;
    int row = 0;
    int arg;

    CALL_SQLITE (open ("/home/ben/test.db", & db));
    sql = "SELECT * FROM t WHERE xyz = ?";
    CALL_SQLITE (prepare_v2 (db, sql, strlen (sql) + 1, & stmt, NULL));
/*
    for (arg = 1; arg < argc; arg++) {
        CALL_SQLITE (bind_text (stmt,
                                1, / * The number of the argument. * /
                                argv[arg],
                                strlen (argv[arg]),
                                0 / * The callback. * /
                               ));
        while (1) {
            int s;

            s = sqlite3_step (stmt);
            if (s == SQLITE_ROW) {
                int bytes;
                const unsigned char * text;
                bytes = sqlite3_column_bytes(stmt, 0);
                text  = sqlite3_column_text (stmt, 0);
                printf ("%d: %s\n", row, text);
                row++;
            } else if (s == SQLITE_DONE) {
                break;
            } else {
                fprintf (stderr, "Failed.\n");
                exit (1);
            }
        }
        CALL_SQLITE (reset (stmt));
        CALL_SQLITE (clear_bindings (stmt));
    }
*/
    return 0;
}

int sqlite3TestInsert() {
    sqlite3 * db;
    char * sql;
    sqlite3_stmt * stmt;
    int i;

    CALL_SQLITE (open ("test.db", & db));
    sql = "INSERT INTO t (xyz) VALUES (?)";
    CALL_SQLITE (prepare_v2 (db, sql, strlen (sql) + 1, & stmt, NULL));
    CALL_SQLITE (bind_text (stmt, 1, "fruit", 6, SQLITE_STATIC));
    CALL_SQLITE_EXPECT (step (stmt), DONE);
    printf ("row id was %d\n", (int) sqlite3_last_insert_rowid (db));
    return 0;
}

int sqlite3TestSelect() {
    sqlite3 * db;
    char * sql;
    sqlite3_stmt * stmt;
    int nrecs;
    char * errmsg;
    int i;
    int row = 0;

    CALL_SQLITE (open ("test.db", & db));
    sql = "SELECT * FROM t";
    CALL_SQLITE (prepare_v2 (db, sql, strlen (sql) + 1, & stmt, NULL));

    while (1) {
        int s;

        s = sqlite3_step (stmt);
        if (s == SQLITE_ROW) {
            int bytes;
            const unsigned char * text;
            bytes = sqlite3_column_bytes(stmt, 0);
            text  = sqlite3_column_text (stmt, 0);
            printf ("%d: %s\n", row, text);
            row++;
        } else if (s == SQLITE_DONE) {
            break;
        } else {
            fprintf (stderr, "Failed.\n");
            exit (1);
        }
    }
    return 0;
}

void Java_uk_co_droidinactu_CalibreImportIntf_helloLog(JNIEnv * env, jobject this, jstring logThis) {
    jboolean isCopy;
    const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);

    (*env)->ReleaseStringUTFChars(env, logThis, szLogThis);
}

jstring Java_uk_co_droidinactu_CalibreImportIntf_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
    return (*env)->NewStringUTF(env, "Hello from native code!");
}

jstring Java_uk_co_droidinactu_CalibreImportIntf_getString(JNIEnv * env, jobject this, jint value1, jint value2) {
    char *szFormat = "The sum of the two numbers is: %i";
    char *szResult;

    // add the two values
    jlong sum = value1+value2;

    // malloc room for the resulting string
    szResult = malloc(sizeof(szFormat) + 20);

    // standard sprintf
    sprintf(szResult, szFormat, sum);

    // get an object string
    jstring result = (*env)->NewStringUTF(env, szResult);

    // cleanup
    free(szResult);

    return result;
}







